<template>
  <BasicModal
    @register="modalRegister"
    :okText="SAVE"
    @ok="save"
    :cancelText="CANCEL"
    @cancel="onCancel"
    destroyOnClose
  >
    <Space direction="vertical">
      <Transfer
        :data-source="roleList"
        :titles="['待选角色', '已选角色']"
        :targetKeys="selectedRoleIdList"
        :showSelectAll="true"
        :lazy="false"
        :render="(item) => item.title"
        @change="roleChange"
      />
      <BasicForm @register="formRegister" />
    </Space>
  </BasicModal>
</template>

<script lang="ts" setup>
  import { ref, unref } from 'vue';
  import { Space, Transfer } from 'ant-design-vue';
  import { isArray } from 'lodash-es';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicForm, useForm } from '/@/components/Form';
  import { CANCEL, SAVE } from '/@/constant';
  import { UserListModel, UserUpdateRoleModel } from '../model';
  import { TransferData } from '/@/model/TransferData';
  import { geAllList } from '../../role/api';
  import { getRoleIdList, updateRole } from '../api';
  import { HOME_PAGE } from '/@/constant/userConstant';
  import { SimpleRoleModel } from '/@/views/system/role/model';
  import { getMenuByIds } from '/@/api/system/permission';

  const emit = defineEmits(['onOk', 'register']);

  const userIds = ref<string[]>([]);
  const roleList = ref<TransferData[]>([]);
  const allRoleList = ref<SimpleRoleModel[]>([]);
  const selectedRoleIdList = ref<string[]>([]);

  const [formRegister, { validate, resetFields, getFieldsValue, setFieldsValue, resetSchema }] =
    useForm({
      baseColProps: {
        span: 24,
      },
      schemas: [
        {
          field: 'homePageId',
          component: 'Select',
          label: HOME_PAGE,
          componentProps: {},
        },
      ],
      showSubmitButton: false,
      showResetButton: false,
      actionColOptions: {
        span: 24,
      },
    });

  const getSingleUserInfo = async (id: string) => {
    // 查询用户拥有的角色
    selectedRoleIdList.value = await getRoleIdList({ id });
  };

  const getAllRole = async () => {
    // 查询所有角色
    allRoleList.value = await geAllList();
    roleList.value = allRoleList.value.map((item) => {
      const { id, name } = item;
      return { key: id, title: name };
    });
  };

  const [modalRegister, { closeModal, setModalProps, changeLoading, changeOkLoading }] =
    useModalInner(async (data: UserListModel | UserListModel[]) => {
      changeLoading(true);

      await getAllRole();

      if (!isArray(data)) {
        const { id, username, homePageId } = data;
        userIds.value = [id];
        await getSingleUserInfo(id);
        setModalProps({
          title: `为 ${username} 关联角色`,
        });
        await setFieldsValue({ homePageId });

        const menus = await getMenus();

        await resetSchema({
          field: 'homePageId',
          component: 'Select',
          label: HOME_PAGE,
          componentProps: {
            options: menus,
            fieldNames: { label: 'title', value: 'id' },
          },
        });
      } else {
        userIds.value = data.map((item) => item.id);
        setModalProps({
          title: `关联角色`,
        });
      }

      changeLoading(false);
    });

  const onCancel = () => {
    selectedRoleIdList.value = [];
    roleList.value = [];
    closeModal();
  };

  const roleChange = async (targetKeys) => {
    selectedRoleIdList.value = targetKeys;
    if (targetKeys && targetKeys.length === 0) {
      await resetMenus([]);
      await setFieldsValue({ homePageId: null });
    } else {
      changeLoading(true);
      const menus = await getMenus();
      await resetMenus(menus);
      await setFieldsValue({ homePageId: menus[0].id });
      changeLoading(false);
    }
  };
  const resetMenus = async (menus) => {
    await resetSchema({
      field: 'homePageId',
      component: 'Select',
      label: HOME_PAGE,
      componentProps: {
        options: menus,
        fieldNames: { label: 'title', value: 'id' },
      },
    });
  };

  const getMenus = async () => {
    const menuIds = allRoleList.value
      .filter((item) => selectedRoleIdList.value.includes(item.id))
      .map((item) => item.homePageId);
    return (await getMenuByIds({ ids: menuIds })).map((item) => {
      return {
        id: item.id,
        title: item.meta?.title,
      };
    });
  };

  const save = async () => {
    const validateRes = await validate();
    if (validateRes) {
      changeLoading(true);
      changeOkLoading(true);

      const ids = unref(userIds);
      const { homePageId } = getFieldsValue();
      const param: UserUpdateRoleModel = { ids, roleIdList: selectedRoleIdList.value, homePageId };
      await updateRole(param);

      closeModal();
      await resetFields();
      selectedRoleIdList.value = [];
      emit('onOk');
      changeLoading(false);
      changeOkLoading(false);
    }
  };
</script>

<style scoped></style>
